package com.wteam.Service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.wteam.PoJo.DO.*;
import com.wteam.PoJo.DTO.CommentDTO;
import com.wteam.PoJo.DTO.PageQuery;
import com.wteam.PoJo.DTO.PostworkDTO;
import com.wteam.PoJo.DTO.ReplyCommentDTO;
import com.wteam.PoJo.VO.CommentVO;
import com.wteam.PoJo.VO.PostworkVO;
import com.wteam.PoJo.VO.ReplyCommentVO;
import com.wteam.framework.common.exception.ServiceException;
import com.wteam.mapper.CommentMapper;
import com.wteam.mapper.PostworkMapper;
import com.wteam.Service.IPostworkService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wteam.mapper.ReplyCommentMapper;
import com.wteam.until.Result;
import com.wteam.until.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 帖子表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-07-16
 */
@Service
@Slf4j
public class PostworkServiceImpl extends ServiceImpl<PostworkMapper, Postwork> implements IPostworkService {
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ReplyCommentMapper replyCommentMapper;

    @Override
    public Result buyorder(PostworkDTO postworkDTO) {
        Long userid = UserContext.getUser();
        Postwork postwork = BeanUtil.copyProperties(postworkDTO, Postwork.class);
        postwork.setUserId(userid);
        save(postwork);
        return Result.success("发布成功");
    }

    @Override
    public Result viewpostwork(PageQuery pageQuery) {
        Page<Postwork> PostworkPage = pageQuery.toMpPage();
        Page<Postwork> page = lambdaQuery().page(PostworkPage);
        //查帖子的
        List<Postwork> records = page.getRecords();
        //将帖子转为帖子VO
        List<PostworkVO> postworkVOS = BeanUtil.copyToList(records, PostworkVO.class);
        //存用户id集合
        List<Long> userIds = postworkVOS.stream().map(PostworkVO::getUserId).collect(Collectors.toList());
        //查贴子作者的姓名和头像
        List<user> userList = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .in(user::getId, userIds).list();

        //用户id和用户关系
        Map<Long, user> collect2 = userList.stream().collect(Collectors.toMap(user::getId, Function.identity()));
        //把作者信息和帖子联系一下
        for (PostworkVO postworkVO : postworkVOS) {
            PostworkVO postwork = (PostworkVO) redisTemplate.opsForValue().get("postwork::"+postworkVO.getId().toString());
            if (BeanUtil.isNotEmpty(postwork)) {
                postworkVO = postwork;
                continue;
            }

            postworkVO.setUsername(collect2.get(postworkVO.getUserId()).getUsername());
            postworkVO.setAvatar(collect2.get(postworkVO.getUserId()).getAvatar());

            //查帖子点赞
            Long count = Db.lambdaQuery(Likes.class).eq(Likes::getUserId, UserContext.getUser())
                    .eq(Likes::getType, 1)
                    .eq(Likes::getParentId, postworkVO.getId())
                    .count();

            if (count != 0) {
                postworkVO.setMylike(true);
            }

            List<Comment> list = Db.lambdaQuery(Comment.class)
                    .eq(Comment::getParentId, postworkVO.getId())
                    .eq(Comment::getType, 1)
                    .eq(Comment::getCommentUserId, postworkVO.getUserId())
                    .orderByDesc(Comment::getLikes)
                    .last("LIMIT 3").list();

            if (CollUtil.isEmpty(list)) {
                redisTemplate.opsForValue().set("postwork::"+postworkVO.getId().toString(),postworkVO);
                continue;
            }
            List<CommentVO> commentVOS = BeanUtil.copyToList(list, CommentVO.class);

            //存用户id集合
            List<Long> CommentuserIds = commentVOS.stream().map(CommentVO::getUserId).collect(Collectors.toList());
            System.out.println(CommentuserIds);

            //查评论者信息
            List<user> CommentuserList = Db.lambdaQuery(user.class)
                    .select(user::getId, user::getAvatar, user::getUsername)
                    .in(user::getId, CommentuserIds)
                    .list();
            //查评论点赞情况
            List<Long> collect = commentVOS.stream().map(CommentVO::getId).collect(Collectors.toList());
            List<Likes> list1 = Db.lambdaQuery(Likes.class)
                    .eq(Likes::getUserId, UserContext.getUser())
                    .eq(Likes::getType, 3)
                    .in(Likes::getCommentId, collect)
                    .list();
            Map<Long, Likes> collect1 = list1.stream().collect(Collectors.toMap(Likes::getCommentId, Function.identity()));
            //用户id和用户关系

            Map<Long, user> collect3 = CommentuserList.stream().collect(Collectors.toMap(user::getId, Function.identity()));
            for (CommentVO commentVO : commentVOS) {
                user user = collect3.get(commentVO.getUserId());
                commentVO.setAvatar(user.getAvatar());
                commentVO.setUsername(user.getUsername());
                if (BeanUtil.isNotEmpty(collect1.get(commentVO.getId()))) {
                    commentVO.setMylike(true);
                }
            }
            postworkVO.setCommentVOS(commentVOS);
            redisTemplate.opsForValue().set("postwork::"+postworkVO.getId().toString(),postworkVO,1,TimeUnit.HOURS);

        }





        return Result.success(postworkVOS);


    }

    @Override
    public Result compostwork(CommentDTO commentDTO) {

        Comment comment = BeanUtil.copyProperties(commentDTO, Comment.class);
        //评论者id
        Long userid = UserContext.getUser();

        comment.setUserId(userid);
        commentMapper.insert(comment);
        //帖子评论数加一
        lambdaUpdate().eq(Postwork::getId, commentDTO.getParentId())
                .setSql("favs = favs+1").update();
        redisTemplate.delete("postwork::"+ commentDTO.getParentId().toString());
        return Result.success("添加成功");
    }

    @Override
    public Result postworkbyId(Long parentId) {
        Postwork postwork = lambdaQuery().eq(Postwork::getId, parentId).one();
        PostworkVO postworkVO = BeanUtil.copyProperties(postwork, PostworkVO.class);
        //查作者信息
        user postuser = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .eq(user::getId, postwork.getUserId()).one();
        postworkVO.setAvatar(postuser.getAvatar());
        postworkVO.setUsername(postuser.getUsername());

        Long userid = UserContext.getUser();
        //查帖子点赞
        Long count = Db.lambdaQuery(Likes.class).eq(Likes::getUserId, userid)
                .eq(Likes::getType, 1)
                .eq(Likes::getParentId, parentId)
                .count();
        System.out.println(count + "ijmomomkm,ko");
        if (count != 0) {
            postworkVO.setMylike(true);
        }


        List<Comment> list = Db.lambdaQuery(Comment.class)
                .eq(Comment::getParentId, postworkVO.getId())
                .eq(Comment::getType, 1)
                .eq(Comment::getCommentUserId, postworkVO.getUserId())
                .orderByDesc(Comment::getLikes)
                .last("LIMIT 3")
                .list();

        if (CollUtil.isEmpty(list)) {
            return Result.success(postworkVO);
        }

        List<CommentVO> commentVOS = TrunComentVOS(list);
        List<Long> collect = commentVOS.stream().map(CommentVO::getId).collect(Collectors.toList());
        List<Likes> list1 = Db.lambdaQuery(Likes.class)
                .eq(Likes::getUserId, userid)
                .eq(Likes::getType, 3)
                .in(Likes::getCommentId, collect)
                .list();
        Map<Long, Likes> collect1 = list1.stream().collect(Collectors.toMap(Likes::getCommentId, Function.identity()));
        for (CommentVO commentVO : commentVOS) {
            if (BeanUtil.isNotEmpty(collect1.get(commentVO.getId()))) {
                commentVO.setMylike(true);
            }

        }


        postworkVO.setCommentVOS(commentVOS);

        return Result.success(postworkVO);
    }

    @Override
    public Result replycomment(ReplyCommentDTO replyCommentDTO) {
        Long userid = UserContext.getUser();
        ReplyComment replyComment = new ReplyComment();
        replyComment.setCommentId(replyCommentDTO.getCommentid());
        replyComment.setCommentUserId(replyCommentDTO.getCommentUserId());
        replyComment.setUserId(userid);
        replyComment.setContent(replyCommentDTO.getContent());
        //给贴子加评论量
        Comment comment1 = Db.lambdaQuery(Comment.class).eq(Comment::getId, replyCommentDTO.getCommentid())
                .select(Comment::getParentId).one();
        lambdaUpdate().eq(Postwork::getId, comment1.getParentId())
                .setSql("favs = favs+1").update();
        //给一级评论表加
        Db.lambdaUpdate(Comment.class).eq(Comment::getId, replyCommentDTO.getCommentid())
                .setSql("replies = replies+1").update();
        replyCommentMapper.insert(replyComment);


        return Result.success("回复成功");
    }

    @Override
    public Result viewreplycomment(Long commentid, PageQuery pageQuery) {


        Page<ReplyComment> commentPage = pageQuery.toMpPage();
        Page<ReplyComment> page = Db.lambdaQuery(ReplyComment.class)
                .page(commentPage);
        List<ReplyComment> records = page.getRecords();
        List<ReplyCommentVO> replyCommentVOS = BeanUtil.copyToList(records, ReplyCommentVO.class);
        if (CollUtil.isEmpty(records)) {
            return Result.success("没有回复");
        }

        //存评论者id集合
        List<Long> CommentuserIds = records.stream().map(ReplyComment::getUserId).collect(Collectors.toList());
        System.out.println(CommentuserIds);

        //查评论者信息
        List<user> CommentuserList = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .in(user::getId, CommentuserIds)
                .list();

        //用户id和用户关系
        Map<Long, user> collect3 = CommentuserList.stream().collect(Collectors.toMap(user::getId, Function.identity()));

        //存被评论者id集合
        List<Long> collect = records.stream().map(ReplyComment::getCommentUserId).collect(Collectors.toList());
        System.out.println(CommentuserIds);

        //查被评论者信息
        List<user> list = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .in(user::getId, collect)
                .list();

        //用户id和用户关系
        Map<Long, user> collect4 = list.stream().collect(Collectors.toMap(user::getId, Function.identity()));

        //查所有回复表id
        List<Long> collect1 = replyCommentVOS.stream().map(ReplyCommentVO::getId).collect(Collectors.toList());
        List<Likes> list1 = Db.lambdaQuery(Likes.class)
                .eq(Likes::getUserId, UserContext.getUser())
                .in(Likes::getReplyId, collect1)
                .eq(Likes::getType, 4)
                .list();
        Map<Long, Likes> collect2 = list1.stream().collect(Collectors.toMap(Likes::getReplyId, Function.identity()));

        for (ReplyCommentVO replyCommentVO : replyCommentVOS) {
            replyCommentVO.setUserAvatar(collect3.get(replyCommentVO.getUserId()).getAvatar());
            replyCommentVO.setUserName(collect3.get(replyCommentVO.getUserId()).getUsername());
            replyCommentVO.setCommentUserName(collect4.get(replyCommentVO.getCommentUserId()).getUsername());
            replyCommentVO.setCommentUserAvatar(collect4.get(replyCommentVO.getCommentUserId()).getAvatar());
            if (BeanUtil.isNotEmpty(collect2.get(replyCommentVO.getId()))) {
                replyCommentVO.setMylike(true);
            }
        }
        return Result.success(replyCommentVOS);


    }

    @Override
    public Result replydelete(Long id) {

        Long UserId = UserContext.getUser();
//查回复表信息
        ReplyComment one = Db.lambdaQuery(ReplyComment.class)
                .eq(ReplyComment::getId, id)
                .eq(ReplyComment::getUserId, UserId)
                .one();
        if (BeanUtil.isEmpty(one)) {
            throw new ServiceException("改信息不是你的，不要乱删别人的信息");
        }
        //删除回复表
        Db.lambdaUpdate(ReplyComment.class)
                .eq(ReplyComment::getId, id)
                .eq(ReplyComment::getUserId, UserId)
                .remove();
        //查一级评论表信息
        Comment one1 = Db.lambdaQuery(Comment.class)
                .select(Comment::getParentId)
                .eq(Comment::getId, one.getCommentId())
                .one();
        //剪回复量
        Db.lambdaUpdate(Comment.class)
                .eq(Comment::getId, one.getCommentId())
                .setSql("replies = replies -1")
                .update();
        lambdaUpdate()
                .eq(Postwork::getId, one1.getParentId())
                .setSql("favs = favs -1")
                .update();
        return Result.success("删除成功");
    }

    @Override
    public Result deletecompostwork(Long id) {
        Long count = Db.lambdaQuery(ReplyComment.class)
                .eq(ReplyComment::getCommentId, id)
                .count();
        Db.lambdaUpdate(ReplyComment.class)
                .eq(ReplyComment::getCommentId, id)
                .remove();
        Comment one = Db.lambdaQuery(Comment.class)
                .eq(Comment::getId, id)
                .eq(Comment::getUserId, UserContext.getUser())
                .select(Comment::getParentId)
                .one();
        Db.lambdaUpdate(Comment.class)
                .eq(Comment::getId, id)
                .remove();
        Postwork one1 = lambdaQuery().eq(Postwork::getId, one.getParentId())
                .select(Postwork::getFavs).one();

        lambdaUpdate().eq(Postwork::getId, one.getParentId())
                .set(Postwork::getFavs, one1.getFavs() - count - 1)
                .update();
        redisTemplate.delete("postwork::"+ one.getParentId().toString());
        return Result.success("删除评论成功");

    }

    @Override
    public Result<List<PostworkVO>> viewmypostwork(PageQuery pageQuery) {
        Page<Postwork> PostworkPage = pageQuery.toMpPage();
        Page<Postwork> page = lambdaQuery().eq(Postwork::getUserId, UserContext.getUser()).page(PostworkPage);
        //查帖子的
        List<Postwork> records = page.getRecords();
        //将帖子转为帖子VO
        List<PostworkVO> postworkVOS = BeanUtil.copyToList(records, PostworkVO.class);
        System.out.println(postworkVOS);
        //查贴子作者的姓名和头像
        user one = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .eq(user::getId, UserContext.getUser()).one();


        //把作者信息和帖子联系一下
        for (PostworkVO postworkVO : postworkVOS) {

            postworkVO.setUsername(one.getUsername());
            postworkVO.setAvatar(one.getAvatar());
        }
        return Result.success(postworkVOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deletemypostwork(Long parentId) {
        //1.删除评价表
        List<Comment> list = Db.lambdaQuery(Comment.class)
                .eq(Comment::getParentId, parentId)
                .eq(Comment::getType, 1)
                .select(Comment::getId)
                .list();
        Db.lambdaUpdate(Comment.class)
                .eq(Comment::getParentId, parentId)
                .eq(Comment::getType, 1)
                .eq(Comment::getCommentUserId, UserContext.getUser())
                .remove();
        //2.删除回复表
        List<Long> collect = list.stream().map(Comment::getId).collect(Collectors.toList());
        List<Long> replyID = new ArrayList();
        if (CollUtil.isNotEmpty(collect)) {
            replyID = Db.lambdaQuery(ReplyComment.class)
                    .in(ReplyComment::getCommentId, collect)
                    .list().stream()
                    .map(ReplyComment::getId)
                    .collect(Collectors.toList());

            Db.lambdaUpdate(ReplyComment.class)
                    .in(ReplyComment::getCommentId, collect)
                    .remove();
        }
        //3.删除贴子
        lambdaUpdate().eq(Postwork::getId, parentId).remove();
        //删除帖子缓存
        redisTemplate.delete("postwork::"+ parentId.toString());

        //4.删除贴子点赞表
        Db.lambdaUpdate(Likes.class)
                .eq(Likes::getParentId, parentId)
                .eq(Likes::getType, 1)
                .remove();
        if (CollUtil.isNotEmpty(collect)) {
            //删除评论点赞
            Db.lambdaUpdate(Likes.class)
                    .in(Likes::getCommentId, collect)
                    .eq(Likes::getType, 3)
                    .remove();
        }
        //删除回复点赞
        if (CollUtil.isNotEmpty(replyID)) {
            Db.lambdaUpdate(Likes.class)
                    .in(Likes::getReplyId, replyID)
                    .eq(Likes::getType, 4)
                    .remove();
        }
        return Result.success("删除成功");
    }

    @Override
    public Result<List<PostworkVO>> followpostwork(PageQuery pageQuery) {

        //查我的关注
        //我的ID
        Long UserId = UserContext.getUser();

        List<Follows> followuser = Db.lambdaQuery(Follows.class).eq(Follows::getUserId, UserId).list();
        if (CollUtil.isEmpty(followuser)) {
            return Result.success("没有了");
        }
        //获取主播的id集合
        List<Long> userids = followuser.stream().map(Follows::getFollowId).collect(Collectors.toList());

        Page<Postwork> PostworkPage = pageQuery.toMpPage();
        Page<Postwork> page = lambdaQuery().in(Postwork::getUserId, userids).page(PostworkPage);
        //查帖子的
        List<Postwork> records = page.getRecords();
        //将帖子转为帖子VO
        List<PostworkVO> postworkVOS = BeanUtil.copyToList(records, PostworkVO.class);
        //存用户id集合
        List<Long> userIds = postworkVOS.stream().map(PostworkVO::getUserId).collect(Collectors.toList());
        //查贴子作者的姓名和头像
        List<user> userList = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .in(user::getId, userIds).list();

        //用户id和用户关系
        Map<Long, user> collect2 = userList.stream().collect(Collectors.toMap(user::getId, Function.identity()));
        //把作者信息和帖子联系一下
        for (PostworkVO postworkVO : postworkVOS) {

            postworkVO.setUsername(collect2.get(postworkVO.getUserId()).getUsername());
            postworkVO.setAvatar(collect2.get(postworkVO.getUserId()).getAvatar());

            //查帖子点赞
            Long count = Db.lambdaQuery(Likes.class).eq(Likes::getUserId, UserContext.getUser())
                    .eq(Likes::getType, 1)
                    .eq(Likes::getParentId, postworkVO.getId())
                    .count();

            if (count != 0) {
                postworkVO.setMylike(true);
            }

            List<Comment> list = Db.lambdaQuery(Comment.class)
                    .eq(Comment::getParentId, postworkVO.getId())
                    .eq(Comment::getType, 1)
                    .eq(Comment::getCommentUserId, postworkVO.getUserId())
                    .orderByDesc(Comment::getLikes)
                    .last("LIMIT 3").list();

            if (CollUtil.isEmpty(list)) {
                continue;
            }
            List<CommentVO> commentVOS = BeanUtil.copyToList(list, CommentVO.class);

            //存用户id集合
            List<Long> CommentuserIds = commentVOS.stream().map(CommentVO::getUserId).collect(Collectors.toList());
            System.out.println(CommentuserIds);

            //查评论者信息
            List<user> CommentuserList = Db.lambdaQuery(user.class)
                    .select(user::getId, user::getAvatar, user::getUsername)
                    .in(user::getId, CommentuserIds)
                    .list();
            //查评论点赞情况
            List<Long> collect = commentVOS.stream().map(CommentVO::getId).collect(Collectors.toList());
            List<Likes> list1 = Db.lambdaQuery(Likes.class)
                    .eq(Likes::getUserId, UserContext.getUser())
                    .eq(Likes::getType, 3)
                    .in(Likes::getCommentId, collect)
                    .list();
            Map<Long, Likes> collect1 = list1.stream().collect(Collectors.toMap(Likes::getCommentId, Function.identity()));
            //用户id和用户关系

            Map<Long, user> collect3 = CommentuserList.stream().collect(Collectors.toMap(user::getId, Function.identity()));
            for (CommentVO commentVO : commentVOS) {
                user user = collect3.get(commentVO.getUserId());
                commentVO.setAvatar(user.getAvatar());
                commentVO.setUsername(user.getUsername());
                if (BeanUtil.isNotEmpty(collect1.get(commentVO.getId()))) {
                    commentVO.setMylike(true);
                }
            }


            postworkVO.setCommentVOS(commentVOS);
        }

        return Result.success(postworkVOS);
    }

    public List<CommentVO> TrunComentVOS(List<Comment> comments) {
        List<CommentVO> commentVOS = BeanUtil.copyToList(comments, CommentVO.class);

        //存用户id集合
        List<Long> CommentuserIds = commentVOS.stream().map(CommentVO::getUserId).collect(Collectors.toList());
        System.out.println(CommentuserIds);

        //查评论者信息
        List<user> CommentuserList = Db.lambdaQuery(user.class)
                .select(user::getId, user::getAvatar, user::getUsername)
                .in(user::getId, CommentuserIds)
                .list();

        //用户id和用户关系
        Map<Long, user> collect3 = CommentuserList.stream().collect(Collectors.toMap(user::getId, Function.identity()));
        for (CommentVO commentVO : commentVOS) {
            user user = collect3.get(commentVO.getUserId());
            commentVO.setAvatar(user.getAvatar());
            commentVO.setUsername(user.getUsername());
        }
        return commentVOS;
    }

}

